from typing import Dict, Optional, List
from pathlib import Path
import platform
import argparse
from .base import BaseTTSEngine
from .gtts_engine import GTTSttsEngine
from .pyttsx3_engine import Pyttsx3TTSEngine
from .macos_say_engine import MacOSSayTTSEngine
from .baidu_engine import BaiduTTSEngine
from .xunfei_engine import XunfeiTTSEngine


class TTSEngineManager:
    """
    TTS引擎管理器，负责创建、选择和管理不同的TTS引擎
    """
    
    def __init__(self, config: Optional[Dict] = None):
        self.config = config or {}
        self.engines = {}
        self._initialize_engines()
    
    def _initialize_engines(self):
        """
        初始化所有可用的TTS引擎
        """
        print("初始化TTS引擎管理器...")
        
        # 初始化各个引擎
        self.engines['gTTS'] = GTTSttsEngine()
        self.engines['pyttsx3'] = Pyttsx3TTSEngine(self.config.get('pyttsx3'))
        self.engines['macos-say'] = MacOSSayTTSEngine()
        self.engines['baidu'] = BaiduTTSEngine(self.config.get('baidu'))
        self.engines['xunfei'] = XunfeiTTSEngine(self.config.get('xunfei'))
        
        # 打印可用引擎信息
        available_engines = [name for name, engine in self.engines.items() if engine.is_available()]
        print(f"可用的TTS引擎: {', '.join(available_engines)}")
    
    @classmethod
    def create_from_config(cls, config: Dict, args: Optional[object] = None) -> 'TTSEngineManager':
        """
        从配置文件和命令行参数创建TTS引擎管理器
        
        Args:
            config: 配置字典
            args: 命令行参数对象
            
        Returns:
            TTSEngineManager: 引擎管理器实例
        """
        engine_config = {}
        
        # 处理百度配置
        baidu_config = None
        if args and hasattr(args, 'baidu_app_id') and args.baidu_app_id and \
           hasattr(args, 'baidu_api_key') and args.baidu_api_key and \
           hasattr(args, 'baidu_secret_key') and args.baidu_secret_key:
            baidu_config = {
                "app_id": args.baidu_app_id,
                "api_key": args.baidu_api_key,
                "secret_key": args.baidu_secret_key
            }
        elif "baidu" in config:
            baidu = config["baidu"]
            if baidu.get("app_id") != "your_app_id" and baidu.get("api_key") and baidu.get("secret_key"):
                baidu_config = baidu
        
        if baidu_config:
            engine_config['baidu'] = baidu_config
        
        # 处理讯飞配置
        xunfei_config = None
        if args and hasattr(args, 'xunfei_app_id') and args.xunfei_app_id and \
           hasattr(args, 'xunfei_api_key') and args.xunfei_api_key:
            xunfei_config = {
                "app_id": args.xunfei_app_id,
                "api_key": args.xunfei_api_key,
                "secret_key": getattr(args, 'xunfei_secret_key', None)
            }
        elif "xunfei" in config:
            xunfei = config["xunfei"]
            if xunfei.get("app_id") != "your_app_id" and xunfei.get("api_key") and xunfei.get("secret_key"):
                xunfei_config = xunfei
        
        if xunfei_config:
            engine_config['xunfei'] = xunfei_config
        
        # 处理pyttsx3配置
        if "pyttsx3" in config:
            engine_config['pyttsx3'] = config["pyttsx3"]
        
        return cls(engine_config)
    
    def get_engine_config(self, engine_name: str) -> Optional[Dict]:
        """获取指定引擎的配置信息。"""
        return self.config.get(engine_name)
    
    def get_engine(self, engine_name: str) -> Optional[BaseTTSEngine]:
        """
        获取指定名称的TTS引擎
        
        Args:
            engine_name: 引擎名称
            
        Returns:
            BaseTTSEngine: TTS引擎实例，如果不存在则返回None
        """
        return self.engines.get(engine_name)
    
    def select_engine(self, engine_name: str, tts_source: str = "auto") -> BaseTTSEngine:
        """
        根据指定的名称和来源选择合适的TTS引擎
        
        Args:
            engine_name: 引擎名称，或"auto"表示自动选择
            tts_source: TTS来源，可选值: "auto", "local", "online"
            
        Returns:
            BaseTTSEngine: 选择的TTS引擎实例
        """
        # 如果明确指定了引擎，尝试获取
        if engine_name != "auto":
            engine = self.get_engine(engine_name)
            if engine and engine.is_available():
                print(f"选择TTS引擎: {engine_name}")
                return engine
            print(f"警告: 指定的引擎 '{engine_name}' 不可用，尝试自动选择")
        
        # 根据来源自动选择引擎
        if tts_source == "local" or (tts_source == "auto" and platform.system() == "Darwin"):
            # 优先使用macOS say命令（如果可用）
            if self.engines['macos-say'].is_available():
                print("自动选择TTS引擎: macos-say")
                return self.engines['macos-say']
            # 否则使用pyttsx3
            if self.engines['pyttsx3'].is_available():
                print("自动选择TTS引擎: pyttsx3")
                return self.engines['pyttsx3']
        
        # 在线引擎优先级
        if tts_source == "online" or tts_source == "auto":
            # 尝试百度引擎
            if self.engines['baidu'].is_available():
                print("自动选择TTS引擎: baidu")
                return self.engines['baidu']
            # 尝试讯飞引擎
            if self.engines['xunfei'].is_available():
                print("自动选择TTS引擎: xunfei")
                return self.engines['xunfei']
            # 尝试gTTS引擎
            if self.engines['gTTS'].is_available():
                print("自动选择TTS引擎: gTTS")
                return self.engines['gTTS']
        
        # 最后回退到可用的本地引擎
        for name in ['pyttsx3', 'macos-say']:
            if self.engines[name].is_available():
                print(f"回退选择TTS引擎: {name}")
                return self.engines[name]
        
        # 如果所有引擎都不可用，抛出异常
        raise RuntimeError("错误: 没有可用的TTS引擎")
    
    def synthesize_text(self, text: str, output_path: Path, 
                       engine_name: str = "auto", 
                       tts_source: str = "auto",
                       lang: str = "en") -> bool:
        """
        合成文本到语音文件
        
        Args:
            text: 要合成的文本
            output_path: 输出文件路径
            engine_name: TTS引擎名称
            tts_source: TTS来源
            lang: 语言代码
            
        Returns:
            bool: 合成是否成功
        """
        # 选择引擎
        engine = self.select_engine(engine_name, tts_source)
        
        # 尝试使用指定引擎合成
        success = engine.synthesize(text, output_path, lang)
        
        # 如果失败，尝试其他引擎作为后备
        if not success:
            print(f"  ℹ {engine.get_name()} 失败，尝试使用其他引擎...")
            
            # 根据来源选择后备引擎
            backup_engines = []
            if tts_source == "local":
                backup_engines = ['pyttsx3', 'macos-say']
            elif tts_source == "online":
                backup_engines = ['baidu', 'xunfei', 'gTTS']
            else:  # auto
                backup_engines = ['pyttsx3', 'macos-say', 'baidu', 'xunfei', 'gTTS']
            
            # 排除已经尝试过的引擎
            for name in backup_engines:
                if name != engine.get_name():
                    backup_engine = self.get_engine(name)
                    if backup_engine and backup_engine.is_available():
                        print(f"  尝试使用后备引擎: {name}")
                        if backup_engine.synthesize(text, output_path, lang):
                            return True
            
            # 如果所有引擎都失败，创建占位文件
            self._create_placeholder_file(text, output_path)
            return False
        
        return success
    
    def _create_placeholder_file(self, text: str, output_path: Path) -> None:
        """
        创建占位文件
        """
        try:
            # 直接创建一个简单的MP3文件头
            with open(output_path, 'wb') as f:
                f.write(b'ID3')  # MP3文件的基本标识
            print(f"  ✓ 生成音节语音: {text} -> {output_path.name} (MP3占位文件)")
        except Exception as e:
            # 如果创建MP3失败，创建文本占位文件
            try:
                output_path.with_suffix('.txt').write_text(f"TTS placeholder for: {text}", encoding="utf-8")
                print(f"  ✓ 生成音节语音: {text} -> {output_path.with_suffix('.txt').name} (文本占位)")
            except Exception as e2:
                print(f"  ⚠ 创建占位文件失败: {e2}")
    
    def get_available_engines(self) -> List[str]:
        """
        获取所有可用的引擎名称
        
        Returns:
            List[str]: 可用引擎名称列表
        """
        return [name for name, engine in self.engines.items() if engine.is_available()]
    
    def cleanup(self):
        """
        清理所有引擎资源
        """
        for engine in self.engines.values():
            try:
                engine.cleanup()
            except Exception:
                pass